#!/usr/bin/python3
# coding=utf-8
#
# Copyright (C) 2023-2024. Huawei Technologies Co., Ltd. All rights reserved.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# ===============================================================================

import sys
import numpy as np
# bfloat16 = tf.bfloat16.as_numpy_dtype

# 针对float32的误差容忍度
relative_tol = 1e-5
absolute_tol = 1e-6
error_tol = 1e-4  # 允许的误差比例上限
data_type = np.float32  # 算子数据类型为float32


def verify_result(output_path, golden_path):
        # 1. 读取实际输出文件（使用 output_path）
    try:
        output = np.fromfile(output_path, dtype=np.float32).reshape(-1)
    except FileNotFoundError:
        return False, f"实际输出文件不存在: {output_path}"
    
    # 2. 读取golden文件（关键修正：使用 golden_path，而非 output）
    try:
        golden = np.fromfile(golden_path, dtype=np.float32).reshape(-1)  # 这里修正变量名
    except FileNotFoundError:
        return False, f"golden文件不存在: {golden_path}"
    
    # 3. 验证形状
    if output.shape != golden.shape:
        return False, f"形状不匹配: output={output.shape}, golden={golden.shape}"
    

   # 4. 误差分析
    abs_error = np.abs(output - golden)
    rel_error = abs_error / (np.abs(golden) + 1e-12)  # 避免除零

    max_abs_error = np.max(abs_error)
    max_rel_error = np.max(rel_error)
    max_idx = np.argmax(abs_error)

    # # 打印前几个差异
    # print(f"\n 误差分析:")
    # for i in range(min(5, len(output))):
    #     print(f" idx={i}: output={output[i]:.6f}, golden={golden[i]:.6f}, "
    #           f"abs_err={abs_error[i]:.6e}, rel_err={rel_error[i]:.6e}")

    # print(f" -> 最大误差位置: {max_idx}, "
    #       f"output={output[max_idx]:.6f}, golden={golden[max_idx]:.6f}, "
    #       f"abs_err={max_abs_error:.6e}, rel_err={max_rel_error:.6e}")

    # 5. 判定是否通过
    if (max_abs_error > error_tol) and (max_rel_error > relative_tol):
        return False, (f"验证失败: "
                       f"最大绝对误差={max_abs_error:.6e} (阈值={error_tol}), "
                       f"最大相对误差={max_rel_error:.6e} (阈值={relative_tol})")
    return True, f"验证通过: 最大绝对误差={max_abs_error:.6e}, 最大相对误差={max_rel_error:.6e}"




if __name__ == '__main__':
    # 验证传入参数
    print("传入的参数列表：", sys.argv)
    if len(sys.argv) != 5:
        print(f"用法: {sys.argv[0]} <output_mean> <output_var> <golden_mean> <golden_var>")
        print(f"示例: {sys.argv[0]} ./output/updated_mean.bin ./output/updated_var.bin "
              "./output/golden_updated_mean.bin ./output/golden_updated_var.bin")
        sys.exit(1)

    # 解析4个参数（顺序：实际mean、实际var、golden mean、golden var）
    output_mean = sys.argv[1]
    output_var = sys.argv[2]
    golden_mean = sys.argv[3]
    golden_var = sys.argv[4]
    
    # 分两次调用函数：先验证mean，再验证var
    mean_ok, mean_msg = verify_result(output_mean, golden_mean)  # 传入2个参数（mean组）
    var_ok, var_msg = verify_result(output_var, golden_var)      # 传入2个参数（var组）

    
    # 输出结果
    if mean_ok and var_ok:
        print("✅ 所有验证通过！")
        sys.exit(0)
    else:
        print("❌ 验证失败！")
        print(f"均值验证: {mean_msg}")
        print(f"方差验证: {var_msg}")
        sys.exit(1)
